package org.kl.bpm.web.conf;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.kl.auditsupervision.entity.fnd.AuditProDtl;
import org.kl.auditsupervision.service.fnd.AuditProDtlService;
import org.kl.bf.entity.basic.User;
import org.kl.bf.entity.easyui.EasyuiGrid;
import org.kl.bf.entity.easyui.EasyuiUtils;
import org.kl.bf.service.basic.CodeValuesService;
import org.kl.bf.service.basic.RoleService;
import org.kl.bf.service.basic.UserService;
import org.kl.bf.web.base.BasicController;
import org.kl.bpm.cmd.DelegateTaskCmd;
import org.kl.bpm.cmd.FindStartFormCmd;
import org.kl.bpm.cmd.FindTaskDefinitionsCmd;
import org.kl.bpm.cmd.HistoryProcessInstanceDiagramCmd;
import org.kl.bpm.cmd.RollbackTaskCmd;
import org.kl.bpm.entity.conf.BpmConfBase;
import org.kl.bpm.entity.conf.BpmConfForm;
import org.kl.bpm.entity.conf.BpmConfNode;
import org.kl.bpm.entity.conf.BpmConfOperation;
import org.kl.bpm.entity.conf.BpmFormTemplate;
import org.kl.bpm.entity.conf.BpmKvProp;
import org.kl.bpm.entity.conf.BpmKvRecord;
import org.kl.bpm.entity.conf.BpmProcess;
import org.kl.bpm.operation.CompleteTaskOperation;
import org.kl.bpm.operation.ConfAssigneeOperation;
import org.kl.bpm.operation.SaveDraftOperation;
import org.kl.bpm.operation.StartProcessOperation;
import org.kl.bpm.service.conf.BpmConfBaseService;
import org.kl.bpm.service.conf.BpmConfFormService;
import org.kl.bpm.service.conf.BpmConfNodeService;
import org.kl.bpm.service.conf.BpmConfOperationService;
import org.kl.bpm.service.conf.BpmFormTemplateService;
import org.kl.bpm.service.conf.BpmKvPropService;
import org.kl.bpm.service.conf.BpmKvRecordService;
import org.kl.bpm.service.conf.BpmProcessService;
import org.kl.bpm.support.FormInfo;
import org.kl.bpm.utils.HistoryTaskOpnion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.modules.web.MediaTypes;
import org.springside.modules.web.Servlets;

/**
 * 流程节点表单配置
 * 
 * @Author hqm
 * @CreateTime 2014年5月29日 上午9:12:11
 */
@Controller
@RequestMapping(value = "/bpm/confForm")
public class BpmConfFormController extends BasicController {
	private static Logger logger = LoggerFactory.getLogger(BpmConfFormController.class);
	@Autowired
	private BpmProcessService bpmProcessService;
	@Autowired
	private BpmConfBaseService bpmConfBaseService;
	@Autowired
	private BpmConfFormService bpmConfFormService;
	@Autowired
	private BpmConfNodeService  bpmConfNodeService;
	@Autowired
	private CodeValuesService codeValuesService;
	@Autowired
	private BpmFormTemplateService bpmFormTemplateService;
	@Autowired
	private BpmConfOperationService bpmConfOperationService;
	@Autowired
	private BpmKvRecordService bpmKvRecordService;
	@Autowired
	private BpmKvPropService bpmKvPropService;

	@Autowired
	private ManagementService managementService;
	@Autowired
	private TaskService taskService;
	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	private FormService formService;
	@Autowired
	private HistoryService historyService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private UserService userService;
	@Autowired
	private AuditProDtlService auditProDtlService;

	@RequestMapping(method = RequestMethod.GET)
	public String list(@RequestParam(value = "bpmConfNodeId", defaultValue = "-1") String bpmConfNodeId, Model model) {
		model.addAttribute("bpmConfNodeId", bpmConfNodeId);
		model.addAttribute("formTemplateList", bpmFormTemplateService.getAllBpmFormTemplate());
		return "bpm/bpmConfFormList";
	}

	// @RequiresPermissions("bpmConfForm:list")
	@RequestMapping(value = "dataGrid", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String dataGrid(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
			@RequestParam(value = "sort", defaultValue = "value") String sortType,
			@RequestParam(value = "order", defaultValue = "asc") String orderType, Model model, ServletRequest request) {
		Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, SEARCH_PREFIX);
		List<BpmConfForm> bpmConfForms = bpmConfFormService.getAllBpmConfForm(searchParams,sortType, orderType);
	
		for (BpmConfForm bcf : bpmConfForms) {
			if (StringUtils.isNotBlank(bcf.getValue())) {
				BpmFormTemplate template = bpmFormTemplateService.getBpmFormTemplate(bcf.getValue());
				if (template != null) {
					bcf.setFormTemplateName(template.getName());
				}
			}
		}
		EasyuiGrid grid = new EasyuiGrid();
		grid.setRows(bpmConfForms);
		grid.setTotal((int) bpmConfForms.size());
		String result = jsonMapper.toJson(grid);
		return result;
	}

	// @RequiresPermissions("bpmConfForm:update")
	@RequestMapping(value = "update", method = RequestMethod.POST)
	@ResponseBody
	public String update(@Valid @ModelAttribute("bpmConfForm") BpmConfForm bpmConfForm, BindingResult result,
			RedirectAttributes redirectAttributes) {
		if (result.hasErrors()) {
			return ajaxMsg(bindingMsg(result), false, null);
		}
		if (bpmConfForm.getBpmConfNode() == null || StringUtils.isBlank(bpmConfForm.getBpmConfNode().getId())) {
			return ajaxMsg("编辑失败，节点标识获取失败，请您刷新页面重试", false, null);
		}
		bpmConfForm.setStatus(1);
		bpmConfFormService.save(bpmConfForm);
		return ajaxMsg("编辑成功", true, null);
	}

	// @RequiresPermissions({ "bpmConfForm:delete",
	// "bpmConfForm:update" })
	@RequestMapping(value = "delete/{id}", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String delete(@PathVariable("id") String id, RedirectAttributes redirectAttributes) {
		bpmConfFormService.delete(id);
		return ajaxMsg("删除成功", true, null);
	}

	/**
	 * 显示启动流程的表单.
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping("form-viewStartForm")
	public String viewStartForm(@RequestParam("bpmProcessId") String bpmProcessId,
			@RequestParam(value = "businessKey", required = false) String businessKey, Model model) throws Exception {
		model.addAttribute("bpmProcessId", bpmProcessId);
		model.addAttribute("businessKey", businessKey);

		BpmProcess bpmProcess = bpmProcessService.getBpmProcess(bpmProcessId);
		String processDefinitionId = bpmProcess.getBpmConfBase().getProcessDefinitionId();

		FormInfo formInfo = managementService.executeCommand(new FindStartFormCmd(processDefinitionId));
		model.addAttribute("formInfo", formInfo);

		String nextStep = null;

		if (formInfo.isFormExists()) {
			// 如果找到了form，就显示表单
			if (bpmProcess.getUseTaskConf() != null && 1 == bpmProcess.getUseTaskConf()) {
				// 如果需要配置负责人
				nextStep = "taskConf";
			} else {
				nextStep = "confirmStartProcess";
			}

			model.addAttribute("nextStep", nextStep);
			BpmConfForm bpmConfForm = bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCode(
					processDefinitionId, formInfo.getNodeCode());
			BpmFormTemplate formTemplate = bpmFormTemplateService.getBpmFormTemplate(bpmConfForm.getValue());

			if (Integer.valueOf(1).equals(formTemplate.getType())) {// 如果为外部表单
				String redirectUrl = formTemplate.getContent();
				return "redirect:" + redirectUrl;
			}

			model.addAttribute("formTemplate", formTemplate);
			BpmKvRecord record = bpmKvRecordService.getBpmKvRecord(businessKey);

			if (record != null) {
				String json = jsonMapper.toJson(record.getProps());
				model.addAttribute("json", json);
			}
			return "bpm/form-viewStartForm";
		} else {
			// 如果没找到form，就判断是否配置负责人
			return taskConf(new LinkedMultiValueMap(), bpmProcessId, businessKey, nextStep, model);
		}
	}

	/**
	 * 配置每个任务的参与人.
	 */
	@RequestMapping("form-taskConf")
	public String taskConf(@RequestParam MultiValueMap<String, String> multiValueMap, @RequestParam("bpmProcessId") String bpmProcessId,
			@RequestParam(value = "businessKey", required = false) String businessKey,
			@RequestParam(value = "nextStep", required = false) String nextStep, Model model) {
		model.addAttribute("bpmProcessId", bpmProcessId);
		Map<String, String[]> parameterMap = new HashMap<String, String[]>();

		for (Map.Entry<String, List<String>> entry : multiValueMap.entrySet()) {
			parameterMap.put(entry.getKey(), entry.getValue().toArray(new String[0]));
		}

		businessKey = new SaveDraftOperation().execute(parameterMap);
		model.addAttribute("businessKey", businessKey);

		BpmProcess bpmProcess = bpmProcessService.getBpmProcess(bpmProcessId);
		String processDefinitionId = bpmProcess.getBpmConfBase().getProcessDefinitionId();

		if (Integer.valueOf(1).equals(bpmProcess.getUseTaskConf())) {
			// 如果需要配置负责人
			nextStep = "confirmStartProcess";
			model.addAttribute("nextStep", nextStep);

			FindTaskDefinitionsCmd cmd = new FindTaskDefinitionsCmd(processDefinitionId);
			List<TaskDefinition> taskDefinitions = managementService.executeCommand(cmd);
			model.addAttribute("taskDefinitions", taskDefinitions);

			return "bpm/form-taskConf";
		} else {
			// 如果不需要配置负责人，就进入确认发起流程的页面
			return confirmStartProcess(bpmProcessId, multiValueMap, model);
		}
	}

	/**
	 * 确认发起流程页面
	 * 
	 * @param bpmProcessId
	 * @param multiValueMap
	 * @param model
	 * @return
	 */
	@RequestMapping("form-confirmStartProcess")
	public String confirmStartProcess(@RequestParam("bpmProcessId") String bpmProcessId,
			@RequestParam MultiValueMap<String, String> multiValueMap, Model model) {
		Map<String, String[]> parameterMap = new HashMap<String, String[]>();

		for (Map.Entry<String, List<String>> entry : multiValueMap.entrySet()) {
			parameterMap.put(entry.getKey(), entry.getValue().toArray(new String[0]));
		}

		String businessKey = new ConfAssigneeOperation().execute(parameterMap);
		String nextStep = "startProcessInstance";
		model.addAttribute("businessKey", businessKey);
		model.addAttribute("nextStep", nextStep);
		model.addAttribute("bpmProcessId", bpmProcessId);

		return "bpm/form-confirmStartProcess";
	}

	/**
	 * 发起流程.
	 */
	@RequestMapping("form-startProcessInstance")
	public String startProcessInstance(@RequestParam MultiValueMap<String, String> multiValueMap, Model model) throws Exception {
		Map<String, String[]> parameterMap = new HashMap<String, String[]>();
		for (Map.Entry<String, List<String>> entry : multiValueMap.entrySet()) {
			parameterMap.put(entry.getKey(), entry.getValue().toArray(new String[0]));
		}
		new StartProcessOperation().execute(parameterMap);
		model.addAttribute("message", "流程发起成功");
		return "bpm/form-message";
	}

	/**
	 * 保存草稿.
	 */
	@RequestMapping("form-saveDraft")
	public String saveDraft(@RequestParam MultiValueMap<String, String> multiValueMap, Model model) throws Exception {
		Map<String, String[]> parameterMap = new HashMap<String, String[]>();
		for (Map.Entry<String, List<String>> entry : multiValueMap.entrySet()) {
			parameterMap.put(entry.getKey(), entry.getValue().toArray(new String[0]));
		}
		new SaveDraftOperation().execute(parameterMap);
		model.addAttribute("message", "草稿保存成功");
		return "bpm/form-message";
	}

	/**
	 * 显示办理任务页面
	 */
	@RequestMapping("form-viewHandleTaskPage")
	public String viewHandleTaskPage(@RequestParam("taskId") String taskId, Model model, RedirectAttributes redirectAttributes)
			throws Exception {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		if (task == null) {
			model.addAttribute("message", "任务[" + taskId + "]不存在");
			return "bpm/form-message";
		}
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId())
				.singleResult();
		BpmConfBase bpmConfBase = bpmConfBaseService.findByProcessDefinitionId(task.getProcessDefinitionId());
		if (bpmConfBase == null) {
			model.addAttribute("message", "流程[" + task.getProcessDefinitionId() + "]不存在");
			return "bpm/form-message";
		}
		BpmProcess bpmProcess = bpmProcessService.findByBpmConfBaseProcessDefinitionKey(bpmConfBase.getProcessDefinitionKey());
		if (bpmProcess == null) {
			model.addAttribute("message", "流程[" + bpmConfBase.getProcessDefinitionKey() + "]不存在");
			return "bpm/form-message";
		}
		model.addAttribute("task", task);
		model.addAttribute("businessKey", processInstance.getBusinessKey());
		List<BpmConfForm> bpmConfFormList= bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCodeAndTypeOrderByCreateTimeAsc(
				bpmConfBase.getProcessDefinitionId(), task.getTaskDefinitionKey(), 1);
		model.addAttribute(
				"bpmConfFormList",bpmConfFormList
				);// 获取所有外部表单
		model.addAttribute("businessFormUrl", bpmProcess == null ? "" : bpmProcess.getBusinessFormUrl());

		model.addAttribute(
				"viewTaskForm",
				bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCodeAndTypeOrderByCreateTimeAsc(
						bpmConfBase.getProcessDefinitionId(), task.getTaskDefinitionKey(), 0).get(0));// 获取第一个内部表单
		return "bpm/form-viewHandleTaskPage";
	}
	
	/**
	 * 已办任务页面查看历史信息，需要考虑两种情形，整个流程完成和整个流程尚未完成
	 * @param taskId
	 * @param historyFlag
	 * @param model
	 * @param redirectAttributes
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("form-viewHisPage")
	public String viewHisPage(@RequestParam("taskId") String taskId,@RequestParam(value="historyFlag",defaultValue="")String historyFlag,Model model, RedirectAttributes redirectAttributes)
			throws Exception {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		if (task == null) {
			HistoricTaskInstance  historicTaskInstance= historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
			model.addAttribute("task",null);
			model.addAttribute("historicTaskInstance", historicTaskInstance);

			HistoricProcessInstance processInstance=historyService.createHistoricProcessInstanceQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).singleResult();
	
			BpmConfBase bpmConfBase = bpmConfBaseService.findByProcessDefinitionId(historicTaskInstance.getProcessDefinitionId());
			if (bpmConfBase == null) {
				model.addAttribute("message", "流程[" + historicTaskInstance.getProcessDefinitionId() + "]不存在");
				return "bpm/form-message";
			}
			BpmProcess bpmProcess = bpmProcessService.findByBpmConfBaseProcessDefinitionKey(bpmConfBase.getProcessDefinitionKey());
			if (bpmProcess == null) {
				model.addAttribute("message", "流程[" + bpmConfBase.getProcessDefinitionKey() + "]不存在");
				return "bpm/form-message";
			}
			model.addAttribute("task", task);
			//model.addAttribute("historicTaskInstance", null);
			model.addAttribute("businessKey", processInstance.getBusinessKey());
			model.addAttribute(
					"bpmConfFormList",
					bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCodeAndTypeOrderByCreateTimeAsc(
							bpmConfBase.getProcessDefinitionId(), historicTaskInstance.getTaskDefinitionKey(), 1));// 获取所有外部表单
			model.addAttribute("businessFormUrl", bpmProcess == null ? "" : bpmProcess.getBusinessFormUrl());
		}else{
			ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId())
					.singleResult();
			
			BpmConfBase bpmConfBase = bpmConfBaseService.findByProcessDefinitionId(task.getProcessDefinitionId());
			if (bpmConfBase == null) {
				model.addAttribute("message", "流程[" + task.getProcessDefinitionId() + "]不存在");
				return "bpm/form-message";
			}
			BpmProcess bpmProcess = bpmProcessService.findByBpmConfBaseProcessDefinitionKey(bpmConfBase.getProcessDefinitionKey());
			if (bpmProcess == null) {
				model.addAttribute("message", "流程[" + bpmConfBase.getProcessDefinitionKey() + "]不存在");
				return "bpm/form-message";
			}
			model.addAttribute("task", task);
			model.addAttribute("historicTaskInstance", null);
			model.addAttribute("businessKey", processInstance.getBusinessKey());
			model.addAttribute(
					"bpmConfFormList",
					bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCodeAndTypeOrderByCreateTimeAsc(
							bpmConfBase.getProcessDefinitionId(), task.getTaskDefinitionKey(), 1));// 获取所有外部表单
			model.addAttribute("businessFormUrl", bpmProcess == null ? "" : bpmProcess.getBusinessFormUrl());
		}
		
		

		model.addAttribute("historyFlag", historyFlag);
		return "bpm/form-viewHandleTaskPage";
	}

	/**
	 * 显示任务表单（使用表单模板生成的任务表单）.
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping("form-viewTaskForm")
	public String viewTaskForm(@RequestParam("taskId") String taskId, Model model, RedirectAttributes redirectAttributes) throws Exception {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		if (task == null) {
			model.addAttribute("message", "任务不存在");
			return "bpm/form-message";
		}
		BpmConfForm bpmConfForm = bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCode(
				task.getProcessDefinitionId(), task.getTaskDefinitionKey());
		BpmFormTemplate formTemplate = bpmFormTemplateService.find(bpmConfForm.getValue());
		formTemplate.setContent(StringUtils.replace(formTemplate.getContent(), CompleteTaskOperation.FORM_FIELD_NAME_VARIABLE,
				task.getTaskDefinitionKey()));// 将表单中${nodeName}用节点定义KEY替换
		model.addAttribute("formTemplate", formTemplate);
		FormInfo formInfo = new FormInfo();
		formInfo.setTaskId(taskId);
		model.addAttribute("formInfo", formInfo);

		List<BpmConfOperation> bpmConfOperations = bpmConfOperationService
				.findByBpmConfNodeCodeAndBpmConfNodeBpmConfBaseProcessDefinitionId(task.getTaskDefinitionKey(),
						task.getProcessDefinitionId());
		for (BpmConfOperation bpmConfOperation : bpmConfOperations) {
			formInfo.getButtons().add(bpmConfOperation.getValue());
		}
		if ((formTemplate != null) && Integer.valueOf(1).equals(formTemplate.getType())) {
			String redirectUrl = formTemplate.getContent() + "?taskId=" + taskId;
			return "redirect:" + redirectUrl;
		}
		if ((taskId != null) && (!"".equals(taskId))) {
			// 如果是任务草稿，直接通过processInstanceId获得record，更新数据
			// TODO: 分支肯定有问题
			String processInstanceId = task.getProcessInstanceId();
			BpmKvRecord record = bpmKvRecordService.findByRef(processInstanceId);
			if (record != null) {
				Map map = new HashMap();
				for (BpmKvProp prop : record.getBpmKvProps()) {
					map.put(prop.getCode(), prop.getValue());
				}
				String json = jsonMapper.toJson(map);
				model.addAttribute("json", json);
			}
		}

		return "bpm/form-viewTaskForm";
	}

	/**
	 * 显示任务表单（使用非表单模板生成的任务表单）.
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping("form-viewTaskForm2")
	public String viewTaskForm2(@RequestParam("taskId") String taskId,@RequestParam(value="formUrl",defaultValue="", required = false) String formUrl,
			Model model, RedirectAttributes redirectAttributes) throws Exception {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		
		if (task == null) {
			model.addAttribute("message", "任务不存在");
			return "bpm/form-message";
		}
		BpmConfForm bpmConfForm = bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCode(
				task.getProcessDefinitionId(), task.getTaskDefinitionKey());
		FormInfo formInfo = new FormInfo();
		formInfo.setTaskId(taskId);
		model.addAttribute("formInfo", formInfo);

		List<BpmConfOperation> bpmConfOperations = bpmConfOperationService
				.findByBpmConfNodeCodeAndBpmConfNodeBpmConfBaseProcessDefinitionId(task.getTaskDefinitionKey(),
						task.getProcessDefinitionId());
		for (BpmConfOperation bpmConfOperation : bpmConfOperations) {
			formInfo.getButtons().add(bpmConfOperation.getValue());
		}		
		BpmConfNode bpmConfNode=bpmConfNodeService.getBpmConfNode(bpmConfForm.getBpmConfNode().getId());
		BpmConfBase bpmConfBase = bpmConfBaseService.findByProcessDefinitionId(task.getProcessDefinitionId());
		BpmProcess bpmProcess = bpmProcessService.findByBpmConfBaseProcessDefinitionKey(bpmConfBase.getProcessDefinitionKey());
		
		String nodeCode=bpmConfNode.getCode();
		model.addAttribute("nodeName",nodeCode);
		if ((taskId != null) && (!"".equals(taskId))) {
			// 如果是任务草稿，直接通过processInstanceId获得record，更新数据
			// TODO: 分支肯定有问题
			String processInstanceId = task.getProcessInstanceId();
			BpmKvRecord record = bpmKvRecordService.findByRef(processInstanceId);
			if (record != null) {
				Map map = new HashMap();
				for (BpmKvProp prop : record.getBpmKvProps()) {
					if(prop.getTaskId()!=null){
						if(prop.getTaskId().equals(taskId)){
							map.put(prop.getCode(), prop.getValue());
						}
					}
				}
				String json = jsonMapper.toJson(map);
				model.addAttribute("json", json);
				model.addAttribute("businessId", record.getBusinessId());
			}
		}
		//指定接收人
		if(StringUtils.isNotEmpty(bpmConfForm.getAssigneeType())){
			String assigneeType=bpmConfForm.getAssigneeType();
			String assigneeValue=bpmConfForm.getAssigneeValue();
			String assigneeUrl = null;
			String trainEmp="1";
			if(assigneeType.equals("0")){//不指定
				
			}else if(assigneeType.equals("1")){//角色
				assigneeUrl ="wfl/assignee/role/"+assigneeValue;
				//assigneeUrl ="wfl/assignee/roleByOrg/"+assigneeValue;
				model.addAttribute("userFlag",getRoleUsers(assigneeValue));
				//model.addAttribute("orgIds","402881ee50c734d60150c74873bd004f");
			}else if(assigneeType.equals("2")){//url
				assigneeUrl =assigneeValue;
				String processInstanceId = task.getProcessInstanceId();
				BpmKvRecord bpmKvRecord = bpmKvRecordService.findByRef(processInstanceId);// 获取审批信息
				List<BpmKvProp> bpmKvPropList=bpmKvPropService.findByRecordIdAndPropCodeOrderByCreateTimeDesc(bpmKvRecord.getId(),"checkboxWF");
				if(bpmKvPropList.size()>0){					
					String checkboxWF=bpmKvPropList.get(0).getValue();
					if(StringUtils.isBlank(checkboxWF)){
						trainEmp="";
					}				
				}
			}else if(assigneeType.equals("3")){//grid
				if(StringUtils.isEmpty(assigneeValue)){
					model.addAttribute("orgId",BasicController.getCurrentUserDeptId());
				}else{
					model.addAttribute("orgId",assigneeValue);
				}
			}
			model.addAttribute("trainEmp",trainEmp);
			model.addAttribute("assigneeUrl",assigneeUrl);
		}
		//指定返回接收人
		if(StringUtils.isNotEmpty(bpmConfForm.getBackAssigneeType())){
			String backAssigneeType=bpmConfForm.getBackAssigneeType();
			String backAssigneeValue=bpmConfForm.getBackAssigneeValue();
			String backAssigneeUrl = null;
			if(backAssigneeType.equals("0")){//不指定
				
			}else if(backAssigneeType.equals("1")){//角色
				backAssigneeUrl ="wfl/assignee/role/"+backAssigneeValue;
			}else if(backAssigneeType.equals("2")){//url
				backAssigneeUrl =backAssigneeValue;
			}
			model.addAttribute("backAssigneeUrl",backAssigneeUrl);
		}
	
		model.addAttribute("beforePostUrl",bpmConfForm.getBeforePostUrl());
		model.addAttribute("afterPostUrl",bpmConfForm.getAfterPostUrl());
		model.addAttribute("processName",bpmProcess.getName());
		model.addAttribute("taskname",task.getName());
		model.addAttribute("receiveMan",BasicController.getCurrentUserName());
		
		
		// 获取任务申报人<以任务时间排序方法>
		List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId()).orderByHistoricTaskInstanceStartTime().asc().list();
		User user = userService.getUser(tasks.get(0).getAssignee());
		model.addAttribute("taskdeclare", user.getTrueName());
		
		// 获取任务内控监督人
		//processInstanceId
		AuditProDtl auditProDtl = auditProDtlService.findByProcessInstanceId(task.getProcessInstanceId());
		if(auditProDtl.getSuperintendent()!=null){
			model.addAttribute("superintendent", auditProDtl.getSuperintendent().getTrueName());
		}
		
		String remark=bpmConfForm.getRemark();
		if(StringUtils.isNoneEmpty(remark)&&auditProDtl.getZgPlanSubTime()!=null){
			remark=remark.replaceAll("\\$\\{zgPlanSubTime\\}", auditProDtl.getZgPlanSubTime().toString().substring(0,auditProDtl.getZgPlanSubTime().toString().indexOf(" ")).replaceAll("(\r\n|\r|\n|\n\r)", "<br>"));
		}
		if(StringUtils.isNoneEmpty(remark)&&auditProDtl.getZgResultSubTime()!=null){
			remark=remark.replaceAll("\\$\\{zgResultSubTime\\}", auditProDtl.getZgResultSubTime().toString().substring(0,auditProDtl.getZgResultSubTime().toString().indexOf(" ")).replaceAll("(\r\n|\r|\n|\n\r)", "<br>"));
		}
		if(StringUtils.isNoneEmpty(remark)){
			remark=remark.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
		}
		model.addAttribute("remark",remark); 
			
		String value = bpmConfForm.getValue();
		BpmFormTemplate bpmFormTemplate = bpmFormTemplateService
				.getBpmFormTemplate(value);
		if (bpmFormTemplate != null) {
			if (bpmFormTemplate.getContent().contains("checkboxWF")) {
				model.addAttribute("checkboxWF", 1);
			} else {
				model.addAttribute("checkboxWF", "");
			}
		} else {
			model.addAttribute("checkboxWF", "");
		}
		 
		if(StringUtils.isEmpty(formUrl)){
			return "bpm/form-viewTaskForm2";
		}
		else{
			return formUrl;					
		}
	}
	
	/**
	 * 获取某个角色下的用户
	 * @param roleNo
	 * @param projectId
	 * @return
	 */
	public String getRoleUsers(String roleNo) {
		List<String> users = userService.getUsersIdByRoleNo(roleNo); 
		if(users.size()>0){
			if(users.size()==1){
				return  users.get(0);
			}else{
				return "2";//标志找到了一个以上的用户
			}
		}else{
			return "0";
		}
	}
	
	/**
	 * 流程启动页面
	 */
	@RequestMapping("from-startProcessPage")
	public String startTaskPage(@RequestParam("processInstanceId") String processInstanceId, 
			Model model,
			RedirectAttributes redirectAttributes)
			throws Exception {
		Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).taskAssignee(BasicController.getCurrentUserId()).active().singleResult();
		if (task == null) {
			model.addAttribute("message", "任务启动出错，缺少启动人表单，请通知系统管理员检查");
			return "bpm/form-message";
		}
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId())
				.singleResult();
		BpmConfBase bpmConfBase = bpmConfBaseService.findByProcessDefinitionId(task.getProcessDefinitionId());
		if (bpmConfBase == null) {
			model.addAttribute("message", "流程[" + task.getProcessDefinitionId() + "]不存在");
			return "bpm/form-message";
		}
		BpmProcess bpmProcess = bpmProcessService.findByBpmConfBaseProcessDefinitionKey(bpmConfBase.getProcessDefinitionKey());
		if (bpmProcess == null) {
			model.addAttribute("message", "流程[" + bpmConfBase.getProcessDefinitionKey() + "]不存在");
			return "bpm/form-message";
		}
		model.addAttribute("task", task);
		model.addAttribute("processName",bpmProcess.getName());
		model.addAttribute("businessKey", processInstance.getBusinessKey());
		model.addAttribute("bpmConfFormList",bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCodeAndTypeOrderByCreateTimeAsc(bpmConfBase.getProcessDefinitionId(), task.getTaskDefinitionKey(), 1));// 获取所有外部表单
		model.addAttribute("businessFormUrl", bpmProcess == null ? "" : bpmProcess.getBusinessFormUrl());
		
		model.addAttribute(
				"viewTaskForm",
				bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCodeAndTypeOrderByCreateTimeAsc(
						bpmConfBase.getProcessDefinitionId(), task.getTaskDefinitionKey(), 0).get(0));// 获取第一个内部表单
		return "bpm/form-viewHandleTaskPage";
	}
	
	/**
	 * 查看历史【包含流程跟踪、任务列表（完成和未完成）】
	 * 
	 * @return
	 */
	@RequestMapping("task-viewHistory")
	public String viewHistory(@RequestParam("processInstanceId") String processInstanceId, Model model) {
		BpmKvRecord bpmKvRecord=bpmKvRecordService.findByRef(processInstanceId);
		List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).orderByHistoricTaskInstanceStartTime().asc()
				.orderByHistoricTaskInstanceStartTime().asc().list();
		List<HistoryTaskOpnion> opinions = new ArrayList<HistoryTaskOpnion>();
		for(HistoricTaskInstance hiTask :historicTasks){
			HistoryTaskOpnion opinion = new HistoryTaskOpnion();
			opinion.setHistoricTaskInstance(hiTask);
			List<BpmKvProp> taskKvPropList = bpmKvPropService.findByTaskId(hiTask.getId());
			for(BpmKvProp prop:taskKvPropList){
				if(prop.getFieldLabel().contains("是否同意")){
					opinion.setOperate(prop.getValue());
				}else if(prop.getFieldLabel().contains("审批意见")){
					opinion.setOpinion(prop.getValue());
				}
			}
			opinions.add(opinion);
		}
		model.addAttribute("processInstanceId", processInstanceId);
		model.addAttribute("bpmKvRecord", bpmKvRecord);
		model.addAttribute("historicTasks", historicTasks);
		model.addAttribute("opinions", opinions);
		
		return "bpm/task-viewHistory";
	}

	/**
	 * 查看历史【流程变量】
	 * 
	 * @return
	 */
	@RequestMapping("task-viewHistoryVariable")
	@ResponseBody
	public String viewHistoryVariable(@RequestParam(value = "taskId", defaultValue = "-1") String taskId, Model model) {
		List<BpmKvProp> taskKvPropList = bpmKvPropService.findByTaskId(taskId);
		return EasyuiUtils.buildEasyuiGridJsonString(taskKvPropList, taskKvPropList.size());
	}

	/**
	 * 完成任务.
	 */
	@RequestMapping("form-completeTask")
	public String completeTask(@RequestParam MultiValueMap<String, String> multiValueMap, RedirectAttributes redirectAttributes, Model model)
			throws Exception {
		Map<String, String[]> parameterMap = new HashMap<String, String[]>();

		for (Map.Entry<String, List<String>> entry : multiValueMap.entrySet()) {
			parameterMap.put(entry.getKey(), entry.getValue().toArray(new String[0]));
		}

		try {
			new CompleteTaskOperation().execute(parameterMap);
		} catch (IllegalStateException ex) {
			logger.error(ex.getMessage(), ex);
			model.addAttribute("message", "ex.getMessage()");
			return "redirect:/bpm/workspace-listPersonalTasks.do";
		}
		model.addAttribute("message", "完成任务");
		return "bpm/form-message";
	}

	/**
	 * 流程跟踪图
	 * 
	 * @throws Exception
	 */
	@RequestMapping("task-graphHistoryProcessInstance")
	public void graphHistoryProcessInstance(@RequestParam("processInstanceId") String processInstanceId, HttpServletResponse response)
			throws Exception {
		Command<InputStream> cmd = new HistoryProcessInstanceDiagramCmd(processInstanceId);
		InputStream is = managementService.executeCommand(cmd);
		response.setContentType("image/png");

		int len = 0;
		byte[] b = new byte[1024];

		while ((len = is.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}

	// ~
	// ==================================国内特色流程====================================
	/**
	 * 回退任务
	 * 
	 * @return
	 */
	@RequestMapping("task-rollback")
	public String rollback(@RequestParam("taskId") String taskId, Model model) {
		Command<Integer> cmd = new RollbackTaskCmd(taskId);
		managementService.executeCommand(cmd);
		model.addAttribute("message", "回退任务成功");
		return "bpm/form-message";
	}

	/**
	 * 转办.
	 */
	@RequestMapping("task-doDelegate")
	public String doDelegate(@RequestParam("taskId") String taskId, @RequestParam("attorney") String attorney, Model model) {
		DelegateTaskCmd cmd = new DelegateTaskCmd(taskId, attorney);
		managementService.executeCommand(cmd);
		model.addAttribute("message", "转办任务成功");
		return "bpm/form-message";
	}

	/**
	 * 协办.
	 */
	@RequestMapping("task-doDelegateHelp")
	public String doDelegateHelp(@RequestParam("taskId") String taskId, @RequestParam("attorney") String attorney, Model model) {
		taskService.delegateTask(taskId, attorney);
		model.addAttribute("message", "协办任务成功");
		return "bpm/form-message";
	}

	/**
	 * 所有RequestMapping方法调用前的Model准备方法, 实现Struts2
	 * Preparable二次部分绑定的效果,先根据form的id从数据库查出Task对象,再把Form提交的内容绑定到该对象上。
	 * 因为仅update()方法的form中有id属性，因此仅在update时实际执行.
	 */
	@ModelAttribute
	public void getBpmConfForm(@RequestParam(value = "id", defaultValue = "-1") String id, Model model) {
		if (!id.equals("-1")) {
			model.addAttribute("bpmConfForm", bpmConfFormService.getBpmConfForm(id));
		}
	}
}
